package fr.utbm.gl52.smartgrid.view;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;

import fr.utbm.gl52.smartgrid.model.device.IDevice;
import fr.utbm.gl52.smartgrid.util.BiControllable;
import fr.utbm.gl52.smartgrid.util.Constants;
import fr.utbm.gl52.smartgrid.util.properties.Properties;
import fr.utbm.gl52.smartgrid.view.listview.ListViewPanel;
import fr.utbm.gl52.smartgrid.view.mainpanel.MainPanel;

public class MainFrame extends JFrame implements BiControllable {

	private static final long serialVersionUID = 4858561039654997695L;

	private ListViewPanel listViewPanel;
	private MainPanel mainPanel;
	private JPanel offPanel;
	private boolean isDisplayingOffPanel;

	public final static int WINDOW_SIZE_X = 800;
	public final static int WINDOW_SIZE_Y = 600;

	public MainFrame() {
		super();

		// Window's properties
		setLayout(new BorderLayout());
		setTitle(Messages.getString("MainFrame.0")); //$NON-NLS-1$
		Dimension size = new Dimension(WINDOW_SIZE_X, WINDOW_SIZE_Y);
		setPreferredSize(size);
		setMinimumSize(size);
		setLocationRelativeTo(null);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		// ListViewPanel, on the left side
		this.listViewPanel = new ListViewPanel();
		// listViewPanel.setPreferredSize(new Dimension(250, 786));
		this.listViewPanel.setPreferredSize(new Dimension(200, 400));

		add(this.listViewPanel, BorderLayout.WEST);

		// Create panel, on the center
		this.mainPanel = new MainPanel(this);
		// add(mainPanel, BorderLayout.CENTER);

		JScrollPane scroll = new JScrollPane(this.listViewPanel); // TODO � tester
		scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		scroll.setPreferredSize(new Dimension(200, getHeight()));

		this.add(scroll, BorderLayout.WEST);

		this.addComponentListener(new ComponentListener() {

			@Override
			public void componentHidden(ComponentEvent arg0) {
				// not used here
			}

			@Override
			public void componentMoved(ComponentEvent arg0) {
				// not used here
			}

			@Override
			public void componentResized(ComponentEvent arg0) {
				/*
				 * int newWidth = arg0.getComponent().getWidth(); int newHeight
				 * = arg0.getComponent().getHeight();
				 * 
				 * if(newWidth!=0) { int newListSizeX = 120 + newWidth -
				 * WINDOW_SIZE_X; int newListSizeY = 786 + newHeight -
				 * WINDOW_SIZE_Y;
				 * 
				 * //MainFrame.this.listViewPanel.setSize(new
				 * Dimension(listViewPanel.getWidth(), newListSizeY));
				 * //MainFrame.this.listViewPanel.setPreferredSize(new
				 * Dimension(listViewPanel.getWidth(), newListSizeY)); }
				 */
			}

			@Override
			public void componentShown(ComponentEvent arg0) {
				// not used
			}

		});

		pack();
		this.offPanel = new JPanel();
		this.add(this.offPanel, BorderLayout.CENTER);
		this.isDisplayingOffPanel = true;
	}

	@Override
	public void addController(ActionListener controller) {
		this.listViewPanel.addController(controller);
		this.mainPanel.addController(controller);
	}

	@Override
	public void addControllers(ActionListener internalController,
			ActionListener externalController) {
		this.listViewPanel.addControllers(internalController, externalController);
		this.mainPanel.addControllers(internalController, externalController);
	}

	public void create(String deviceType) {

		// Extraire le nom de la classe
		try {
			if (deviceType.equals(Constants.TYPE_LOAD))
				this.mainPanel.setTypeSelectorPanel(Class
						.forName(Constants.TYPE_LOAD));
			else if (deviceType.equals(Constants.TYPE_SOURCE))
				this.mainPanel.setTypeSelectorPanel(Class
						.forName(Constants.TYPE_SOURCE));
			else if (deviceType.equals(Constants.TYPE_STORAGE))
				this.mainPanel.setTypeSelectorPanel(Class
						.forName(Constants.TYPE_STORAGE));
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			if (Constants.isDebug)
				System.out.println("ERROR : can't find class name"); //$NON-NLS-1$
		}
		this.isDisplayingOffPanel = false;
		switchPanels();
	}

	public void edit(UUID id, Map<String, Properties<?>> properties) {
		setPropertyEditorPanel(id, properties);
		this.mainPanel.hideTypeSelectorPanel();
		this.isDisplayingOffPanel = false;
		switchPanels();
	}

	public void update(Collection<IDevice> deviceList) {
		this.listViewPanel.update(deviceList);
	}

	/*
	 * @Deprecated> public void setPropertyEditorPanel(IDevice device) {
	 * mainPanel.setPropertyEditorPanel(device.getID(), device.getProperties());
	 * }
	 */

	public MainPanel getMainPanel() {
		return this.mainPanel;
	}

	public void setPropertyEditorPanel(UUID uuid,
			Map<String, Properties<?>> properties) {
		this.mainPanel.setPropertyEditorPanel(uuid, properties);
	}

	public JPanel getOffPanel() {
		return this.offPanel;
	}

	public void setOffPanel(JPanel offPanel) {
		this.offPanel = offPanel;
	}

	public void switchPanels() {
		if (this.isDisplayingOffPanel) {
			this.remove(this.mainPanel);
			this.add(this.offPanel, BorderLayout.CENTER);
		} else {
			this.remove(this.offPanel);
			this.add(this.mainPanel, BorderLayout.CENTER);
		}
		revalidate();
		repaint();
	}

	public boolean isDisplayingOffPanel() {
		return this.isDisplayingOffPanel;
	}

	public void setDisplayingOffPanel(boolean isDisplayingOffPanel) {
		this.isDisplayingOffPanel = isDisplayingOffPanel;
	}

}
